package com.wyh.controller.gfive;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.wyh.common.result.InvoicerecordsShowResult;
import com.wyh.common.result.Result;
import com.wyh.common.utils.FileName;
import com.wyh.common.utils.QRCodeUntil;
import com.wyh.common.utils.ali.AliOssUtil;
import com.wyh.common.utils.pdfToPng;
import com.wyh.domain.po.gfive.Invoicerecords;
import com.wyh.domain.po.gfive.InvoicerecordsFind;
import com.wyh.domain.po.gfive.PageHelper;
import com.wyh.domain.po.gfive.Invoicedetails;
import com.wyh.domain.vo.gfive.*;
import com.wyh.service.gfive.*;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

@RestController
@RequestMapping("InvoiceRecords")
@Slf4j
@Api(tags = "票据管理")
public class InvoicerecordsController {
    @Resource
    private InvoicerecordsServiceVO InService;
    @Resource
    private InvoicerecordsDTOService InServiceDTO;
    @Resource
    private com.wyh.service.gfive.invoicedetailsService InvoiceDetailService;


    @Resource
    private InvoicetypeService InvoType;
    @Value("${upload.path}")
    private String uploadPath;
    @Value("${upload.Url}")
    private String URL;

    @Value("${upload.outPath}")
    private String outPath;

    @Resource
    private InvoicerecordsService invoicerecordsService;
    @Resource
    private invoicedetailsService invoicedetailsService;


    /**
     * 分页显示 分页显示 已经上传票据的信息
     */
    @PostMapping("/showInvoiceRecords")
    @ApiOperation(value = "显示已经已上传票据数据")
    public Result showAll(@RequestBody PageHelper pageHelper) {
        Result result = InService.showPage((pageHelper.getCurrentPage() - 1) * pageHelper.getPageSize(), pageHelper.getPageSize());
        return result;
    }

    /**
     * 推送 即返回手机号 以及邮箱
     */
    @GetMapping("/returnEmail")
    @ApiOperation(value = "推送信息")
    @ApiImplicitParam(name = "Invoicecode", value = "发票代码", required = true)
    public Result email(@RequestParam("Invoicecode") String Invoicecode) {
        if (Invoicecode.isEmpty()) {
            return Result.error();
        }
        Result result = InService.lookCustomer(Invoicecode);
        return result;
    }

    /**
     * 撤销 已上传的发票
     */
    @GetMapping("/comBack")
    @Transactional
    @ApiOperation(value = "撤销已上传发票")
    public Result back(@RequestParam("Invoicecode") String Invoicecode) {
        boolean flag = false;
        QueryWrapper<Invoicerecords> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("Invoicecode", Invoicecode);
        Invoicerecords one = InServiceDTO.getOne(queryWrapper);
        Integer state = one.getState();
        if (state == 0) {
            return Result.error("改票据已经撤销，不允许重复撤销");
        }

        UpdateWrapper<Invoicerecords> wrapper = new UpdateWrapper<>();
        wrapper.eq("Invoicecode", Invoicecode).set("state", 0);
        boolean update = InServiceDTO.update(wrapper);
        log.info("{}", update);
        if (!update) {
            return Result.error("撤销失败");
        }
        flag = true;
        //通知账单 进行金额的回滚
        if (flag) {
            this.backMoney(Invoicecode);
        }
        return Result.success("撤销成功");
    }

    /**
     * 撤销后通知其进行金额的回滚
     */
    @PostMapping("/BackMonry")
    @ApiOperation(value = "撤销后金额回滚")
    public Result backMoney(@RequestParam("Invoicecode") String Invoicecode) {
        log.info("传过来的数据为{}", Invoicecode);
        Result result = InServiceDTO.moneyBack(Invoicecode);
        return result;
    }

    /**
     * 查询 票据信息
     */
    @PostMapping("/query")
    @ApiOperation(value = "查询票据(已上传票据)")
    public Result myQuery(@RequestBody InvoicereordsSelectVo invoicerecordsSelectVO) {
        if (invoicerecordsSelectVO == null || invoicerecordsSelectVO.isEmptyT()) {
            log.info("进入到了这里");
            return Result.error("请输入查询条件！！");
        }
        Result result = InService.selectInvoicerecords(invoicerecordsSelectVO);
        return result;
    }

    /**
     * 在账户管理里添加是 这边生成一个 票据
     */
    @GetMapping("/addInvoicerecords")
    @ApiOperation("生成票据")
    public Result addInvoicerecords(@RequestParam(value = "invoType", required = true) Integer invoType,
                                    @RequestParam(value = "salesside", required = true) String salesside,
                                    @RequestParam(value = "Type", required = true) Integer Type,
                                    @RequestParam(value = "amount", required = true) Double amount,
                                    @RequestParam(value = "billid", required = true) Integer billid) {
        Result result = InServiceDTO.addInvoicerecords(invoType, salesside, amount, Type, billid);
        return result;
    }

    /**
     * 分页展示 待处理 的票据
     */
    @PostMapping("/invoicerecordsNo")
    @ApiOperation(value = "显示待处理票据信息")
    public Result showInvoicerecordsNo(@RequestBody PageHelper pageHelper) {
        Result result = InServiceDTO.showInvoicerecordsNoPage((pageHelper.getCurrentPage() - 1) * pageHelper.getPageSize(), pageHelper.getPageSize());
        return result;
    }

    /**
     * 查询 待处理的票据  查询是必须输入 购买方或者业主方的其中一个
     */
    @PostMapping("/queryNoInvoicerecords")
    @ApiOperation(value = "查询待处理票据（必须输入 购买方或者业主方的其中一个）")
    public Result myQueryNo(@RequestBody InvoicerecordsSelectNoVo InvoSelectNoVO) {
        log.info("传入的数据为{}", InvoSelectNoVO);
        if (InvoSelectNoVO == null || InvoSelectNoVO.isEmptyT()) {
            return Result.error("请输入查询条件！！");
        }
        Result result = InServiceDTO.selectNoInvoicerecords(InvoSelectNoVO);
        return result;
    }


    /**
     * 上传发票
     */
    @PostMapping("/upload")
    @Transactional
    @ApiOperation(value = "上传传票")
    public Result handleFile(@RequestParam("file") MultipartFile file, @RequestParam("noticenumber") String noticenumber) {
        try {
            // 获取文件名
            String fileName = file.getOriginalFilename();
            log.info("文件名为{}", fileName);

            // 将文件以流的方式传递给二维码解析工具
            List<String> show1 = QRCodeUntil.show(file.getInputStream());
            if ( show1.isEmpty()) {
                return Result.success("在pdf中没有检测到二维码");
            } else {
                // 解析二维码数据
                String strNumber = show1.get(0);
                Double aDouble = QRCodeUntil.SswitchNumber(show1.get(1));
                LocalDate localDate = QRCodeUntil.SswitchD(show1.get(2));

                // 通过发票编号查询 id 号
                QueryWrapper<Invoicerecords> queryWrapper = new QueryWrapper<>();
                queryWrapper.select("id", "state").eq("noticenumber", noticenumber).eq("type", 0);
                Invoicerecords one = InServiceDTO.getOne(queryWrapper);
                if (one == null) {
                    return Result.error("数据异常");
                }

                UpdateWrapper<Invoicerecords> wrapper = new UpdateWrapper<>();
                wrapper.eq("noticenumber", noticenumber)
                        .set("Invoicenumber", strNumber)
                        .set("Invoicingtime", localDate)
                        .setSql("amount=amount+" + aDouble);
                boolean update = InServiceDTO.update(wrapper);
                if (!update) {
                    return Result.error("数据异常");
                }

                // 查询添加后的金额是否等于应付金额
                UpdateWrapper<Invoicerecords> newDate = new UpdateWrapper<>();
                newDate.eq("noticenumber", noticenumber);
                Invoicerecords one1 = InServiceDTO.getOne(newDate);

                // 通过订单 id 查询应付金额
                Integer billid = one1.getBillid();
                Double aDouble1 = InServiceDTO.selectAllMoney(billid);

                if (Objects.equals(one1.getAmount(), aDouble1)) {
                    // 更新状态为 2
                    UpdateWrapper<Invoicerecords> invoicerecordsUpdateWrapper = new UpdateWrapper<>();
                    invoicerecordsUpdateWrapper.eq("noticenumber", noticenumber).set("state", 2);
                    boolean update1 = InServiceDTO.update(invoicerecordsUpdateWrapper);
                    if (!update1) {
                        return Result.error("数据异常！！");
                    }
                }

                // 将 PDF 和转换的 PNG 上传到 OSS，并将数据存入数据库
                try {
                    // 获取存入oss文件名
                    String name = FileName.name(fileName);
                    log.info("文件名是{}", name);
                    // 将读取有数据的 PDF 存入 OSS 中
                    String url = AliOssUtil.uploadFile(name, file.getInputStream());

                    // PDF 转换为 PNG 地址
//                    pngPath = pdfToPng.convertPdfToImage(file.getInputStream(), outPath);
                    InputStream inputStream = pdfToPng.convertPdfToImage(file.getInputStream());

                    //获取转换的png文件名（只截取文件名和添加 文件后缀）
                    String pngName = pdfToPng.extractFileName(fileName);
                    log.info("转换后的温江名{}", pngName);
                    String name1 = FileName.name(pngName);

                    // 将转换后的 PNG 上传到 OSS 上
                    String pngUrl = AliOssUtil.uploadFile(name1, inputStream);

                    Invoicedetails invoicedetails = new Invoicedetails(localDate, pngUrl, strNumber, aDouble, 0, one.getId());

                    if (invoicedetails == null) {
                        return Result.error("数据异常");
                    }

                    boolean save = invoicedetailsService.save(invoicedetails);
                    if (!save) {
                        return Result.error("数据异常！！");
                    }
                } catch (IOException e) {
                    throw new RuntimeException("转换异常");
                }
                return Result.success(show1);
            }

        } catch (IOException e) {
            e.printStackTrace();
            return Result.error("上传失败");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    /**
     * 分页查询所有的收据
     */
    @GetMapping("/findAll")
    @ApiOperation(value = "【收据】分页展示所有的收据")
    public Result findAll(@Param("currentPage") Integer currentPage, @Param("pageSize") Integer pageSize) {
        PageHelper pageHelper = new PageHelper(currentPage, pageSize);
        List<InvoicerecordsShowResult> all = invoicerecordsService.findAll(pageHelper);
        return Result.success(all, (long) all.size());
    }

    /**
     * 根据条件查找收据
     */
    @PostMapping("/selectInvoicerecords")
    @ApiOperation(value = "【收据】根据条件查询分页展示收据")
    public Result selectInvoicerecords(@RequestBody InvoicerecordsFind invoicerecordsFind) {
        InvoicerecordsShowResult invoicerecordsShowResult =new InvoicerecordsShowResult();
        if (invoicerecordsFind.getMinPrice()!=0.0){
            invoicerecordsShowResult.setMinPrice(invoicerecordsFind.getMinPrice());
        }else {
            invoicerecordsShowResult.setMinPrice(0.0);
        }
        if (invoicerecordsFind.getMaxPrice()!=0.0){
            invoicerecordsShowResult.setMaxPrice(invoicerecordsFind.getMaxPrice());
        }else {
            invoicerecordsShowResult.setMaxPrice(0.0);
        }
        PageHelper pageHelper = new PageHelper();
        pageHelper.setCurrentPage(invoicerecordsFind.getCurrentPage());
        pageHelper.setPageSize(invoicerecordsFind.getPageSize());

        invoicerecordsShowResult.setName(invoicerecordsFind.getName());
        invoicerecordsShowResult.setAmount(invoicerecordsFind.getAmount());
        invoicerecordsShowResult.setInvoicingtime(invoicerecordsFind.getInvoicingtime());
        invoicerecordsShowResult.setReceiptnumber(invoicerecordsFind.getReceiptnumber());
        invoicerecordsShowResult.setNoticenumber(invoicerecordsFind.getNoticenumber());

        List<InvoicerecordsShowResult> list = invoicerecordsService.findInvoicerecords(invoicerecordsShowResult, pageHelper);
        return Result.success(list, (long) list.size());
    }

    /**
     * 点击推送后弹出 手机号及邮箱
     */
    @PostMapping("/sendEmail")
    @ApiOperation(value = "【收据】点击推送后弹出 手机号及邮箱")
    @ApiImplicitParam(name = "InvoicecodeId", value = "收据id", required = true)
    public Result emailTo(@RequestParam("InvoicecodeId") Integer InvoicecodeId) {
        if (InvoicecodeId == null || InvoicecodeId.equals(' ')) {
            return Result.error("请检查传入数据是否为空数据");
        }
        Integer customerId = invoicerecordsService.findCustomerId(InvoicecodeId);
        if (customerId == null || customerId.equals(' ')) {
            return Result.error("并未找到该用户信息");
        }
        TelAndEmailVO telAndEmail = invoicerecordsService.findTelAndEmail(customerId);
        if (telAndEmail == null) {
            return Result.error("在收据表中并未查找到用户信息！");
        }
        return Result.success(telAndEmail);
    }


    //直接返会oss的png地址
    @GetMapping("/getPngOSS")
    @ApiOperation(value = "直接返回oss里面对png 的URL")
    public Result getpngOssUrl(@RequestParam("noticenumber") String noticenumber) {
        List<String> pngUrl = new ArrayList<>();
//        //根据通知单编号查询id
//        QueryWrapper<Invoicerecords> wrapper = new QueryWrapper<>();
//        wrapper.eq("noticenumber", noticenumber);
//        //获取id
//        Invoicerecords one = InServiceDTO.getOne(wrapper);
//        if (one == null) {
//            return Result.error("数据异常");
//        }
//        Integer id = one.getId();
//        //根据票据id，查询票据详情表里面的存储数据
//        QueryWrapper<Invoicedetails> queryWrapper = new QueryWrapper<>();
//        queryWrapper.eq("invoice_id", id);
//        List<Invoicedetails> list = InvoiceDetailService.list(queryWrapper);
//        List<String> urlList = list.stream().map(Invoicedetails::getUrl).collect(Collectors.toList());
//
//
//
//        int urlNumber = urlList.size();
//        log.info("截取出来的路径数据{}", urlList);
//        boolean b = pngUrl.addAll(urlList);

        Result result = InServiceDTO.selectOther(noticenumber);


//        return Result.success(pngUrl, Long.valueOf(urlNumber));
        return result;
    }

    //返回 待处理发票的图片以及 数据


    /**
     * 返回多张票据pdf
     */
//    @GetMapping("/getPdfFiles")
//    @ApiOperation(value = "返回多张票据第一个接口")
//    public ResponseEntity<List<String>> getPdfFiles(@RequestParam("noticenumber") String noticenumber) {
//        List<String> pdfUrls = new ArrayList<>();
//        //根据通知单编号查询id
//        QueryWrapper<Invoicerecordes> wrapper = new QueryWrapper<>();
//        wrapper.eq("noticenumber", noticenumber);
//        //获取id
//        Invoicerecordes one = InServiceDTO.getOne(wrapper);
//        Integer id = one.getId();
//        //根据票据id，查询票据详情表里面的存储数据
//        QueryWrapper<Invoicedetails> queryWrapper = new QueryWrapper<>();
//        queryWrapper.eq("invoice_id",id);
//        List<Invoicedetails> list = InvoiceDetailService.list(queryWrapper);
//
//        List<String> urlList = list.stream().map(Invoicedetails::getUrl).collect(Collectors.toList());
//        log.info("截取出来的路径数据{}",urlList);
//        List<String> fileNames = urlList.stream().map(UrlUNtil::extractFileName).collect(Collectors.toList());
//        log.info("截取的pdf文件名为{}",fileNames);
//
//        for (String fileName : fileNames) {
//
//            try {
//                Path filePath = Paths.get(uploadPath).resolve(fileName).normalize();
//                org.springframework.core.io.Resourcees resource = new UrlResource(filePath.toUri());
//
//                if (resource.exists() && resource.isReadable()) {
////                    String url = URL + fileName;
//                    String url = URL + fileName;
//                    pdfUrls.add(url);
//                }
//            } catch (MalformedURLException e) {
//                e.printStackTrace();
//            }
//        }
//
//        return ResponseEntity.ok().body(pdfUrls);
//    }


    /**
     * 查看 票据信息
     */
//    @PostMapping("/images")
//    @GetMapping("/images/{fileName}")
//    @ApiOperation(value = "返回多张票据第二个接口")
//    public ResponseEntity<org.springframework.core.io.Resourcees> getImage(@PathVariable String fileName) throws IOException {
//
//        Path filePath = Paths.get(uploadPath).resolve(fileName).normalize();
//        File file = filePath.toFile();
//        log.info("file地址为：{}", file);
//
//        org.springframework.core.io.Resourcees resource = new UrlResource(file.toURI());
//        String contentType = Files.probeContentType(filePath);
//
//        if (contentType == null) {
//            contentType = "application/octet-stream";
//        }
//        log.info("数据格式为+{}", contentType);
//
//        log.info("file.getName()的=千为{}", file.getName());
//        return ResponseEntity.ok()
//                .contentType(MediaType.parseMediaType(contentType))
//                .header(HttpHeaders.CONTENT_DISPOSITION, "inline; filename=\"" + file.getName() + "\"")
//                .body(resource);
//    }

    /**
     * 撤销 已上传的收据
     */
    @PostMapping("/comesBack")
    @Transactional
    @ApiOperation(value = "【收据】撤销已上传的收据")
    public Result ComesBack(@RequestParam("InvoicecodeId") Integer InvoicecodeId) {
        boolean flag = false;
        UpdateWrapper<Invoicerecords> wrapper = new UpdateWrapper<>();
        wrapper.eq("id", InvoicecodeId).set("state", 0);
        boolean update = InServiceDTO.update(wrapper);
        log.info("{}", update);
        if (!update) {
            return Result.error("撤销失败");
        }
        flag = true;
        //通知账单 进行金额的回滚
        if (flag) {
            this.backsMoney(InvoicecodeId);
        }
        return Result.success("撤销成功");
    }

    /**
     * 撤销后通知其进行金额的回滚
     */
    @PostMapping("/BacksMonry")
    @ApiOperation(value = " 【收据】撤销后通知其进行金额的回滚（后端完成无需前端调用）")
    public Result backsMoney(@RequestParam("Invoicecode") Integer Invoicecode) {
        Result result = invoicerecordsService.moneyBack(Invoicecode);
        return result;
    }


    /**
     * 查看收据
     */
    @GetMapping("/seeInvoicerecord")
    @ApiOperation("查看收据")
    public Result<List<Invoicedetails>> seeInvoicerecord(
            String receiptnumber
    ) {
        List<Invoicedetails> invoicedetails = invoicerecordsService.seeInvoicedetails(receiptnumber);
        return Result.success(invoicedetails);
    }

    /**
     * 发送邮箱
     */
    @PostMapping("/email")
    @ApiOperation("发送邮箱信息")
    public Result sendEmailAndMessage(@RequestParam("receiptnumber") String receiptnumber, @RequestParam("telAndEmailVO") String telAndEmailVO) {

        invoicerecordsService.sendEmail(telAndEmailVO, receiptnumber);
        return Result.success();
    }
}
